package com.rc.evcharger.service;

import com.rc.evcharger.biz.log.ChargedProcessLogAssemble;
import com.rc.evcharger.common.code.StdControlCode;
import com.rc.evcharger.common.config.RemoteUpdateConfig;
import com.rc.evcharger.common.constant.SocketConstant;
import com.rc.evcharger.common.constant.WebConstant;
import com.rc.evcharger.common.enums.ChargePhaseEnum;
import com.rc.evcharger.common.enums.CommanderEnum;
import com.rc.evcharger.common.type.*;
import com.rc.evcharger.common.utils.DataUtil;
import com.rc.evcharger.common.utils.ToFrameUtil;
import com.rc.evcharger.component.UidGenerator;
import com.rc.evcharger.mapper.member.MemberAccountMapper;
import com.rc.evcharger.model.elec.ElecGun;
import com.rc.evcharger.model.elec.ElecPile;
import com.rc.evcharger.model.elec.ElecStation;
import com.rc.evcharger.model.hlhtbill.HlhtTenantOrderNotify;
import com.rc.evcharger.model.hlhtsk.HlhtskBizOperator;
import com.rc.evcharger.model.member.MemberAccount;
import com.rc.evcharger.model.member.MemberInfo;
import com.rc.evcharger.model.order.OrderComment;
import com.rc.evcharger.model.order.OrderInfo;
import com.rc.evcharger.redis.RedChargeDataService;
import com.rc.evcharger.redis.RedisService;
import com.rc.evcharger.service.elec.ElecGunService;
import com.rc.evcharger.service.elec.ElecPileService;
import com.rc.evcharger.service.elec.ElecStationPriceService;
import com.rc.evcharger.service.elec.ElecStationService;
import com.rc.evcharger.service.enterprise.EnterpriseSubmemberShareService;
import com.rc.evcharger.service.hlhtbill.HlhtTenantOrderNotifyService;
import com.rc.evcharger.service.hlhtsk.HlhtskBizOperatorService;
import com.rc.evcharger.service.member.MemberInfoService;
import com.rc.evcharger.service.order.OrderCommentService;
import com.rc.evcharger.service.order.OrderInfoService;
import com.rc.evcharger.service.tenant.TenantManufacturerService;
import com.rc.evcharger.service.tenant.TenantSettingService;
import com.rc.evcharger.vo.charge.PowerOffReq;
import com.rc.evcharger.vo.charge.StartChargeReq;
import com.rc.evcharger.vo.charge.StopChargeReq;
import com.rc.evcharger.vo.charge.UserAccountReq;
import com.rc.evcharger.dto.msg.TerminalMessage;
import com.rc.evcharger.netty.server.MessageHandler;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;

/**
 * 所有充电前端(公众号/APP/API)向桩发送指令
 */
@Service
public class CommandServiceImpl implements CommandService {
    private static Logger logger = LoggerFactory.getLogger(CommandServiceImpl.class);

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    private RemoteUpdateConfig remoteUpdateConfig;

    @Autowired
    private MemberInfoService memberInfoService;

    @Autowired
    private ElecGunService elecGunService;

    @Autowired
    private ElecPileService elecPileService;

    @Autowired
    private ElecStationService elecStationService;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ChargedProcessLogAssemble chargedProcessLogAssemble;

    @Autowired
    private OrderCommentService orderCommentService;

    @Autowired
    private MemberAccountMapper memberAccountMapper;

    @Autowired
    private RedChargeDataService redChargeDataService;

    @Autowired
    private TenantSettingService tenantSettingService;

    @Autowired
    private HlhtTenantOrderNotifyService hlhtTenantOrderNotifyService;

    @Autowired
    private EnterpriseSubmemberShareService enterpriseSubmemberShareService;

    @Autowired
    private TenantManufacturerService tenantManufacturerService;

    @Autowired
    private ElecStationPriceService elecStationPriceService;

    @Autowired
    private HlhtskBizOperatorService hlhtskBizOperatorService;

    @Override
    public Integer query_start_charge(StartChargeReq startChargeReq) {
        //充电枪验证消息
        Integer checkStartResult = checkStart(startChargeReq);
        if (SocketConstant.SUCCESS != checkStartResult) {
            return checkStartResult;
        }

        ElecPile elecPile = elecPileService.selectByPrimaryKey(startChargeReq.getElecPileId());
        ElecGun elecGun = elecGunService.validGun(elecPile, startChargeReq.getGunNum());

        //桩群信息
        ElecStation elecStation = elecStationService.selectByPrimaryKey(elecPile.getElecStationId());

        // 生成内部订单流水号
        String orderNum = uidGenerator.genChargeOrderNum(elecGun.getGunNo());
        if (StringUtils.isBlank(orderNum)) {
            logger.error("无法生成充电订单号码，枪号为,:{},:{}", elecPile.getPileNo(), startChargeReq.getGunNum());
            return SocketConstant.FAIL;
        }

        MemberAccount memberAccount = memberAccountMapper.selectByPrimaryKey(startChargeReq.getMemberId());
        BigDecimal money;
        if ((SocketConstant.CON0 + "").equals(startChargeReq.getAccountType())) {
            money = memberAccount.getAccount();
        } else if (SocketConstant.STR_CON2.equals(startChargeReq.getAccountType())) {
            money = enterpriseSubmemberShareService.selectMoneyByTenantCodeAndMemberId(memberAccount.getTenantCode(), memberAccount.getMemberId());
        }else {
            money = memberAccount.getEnterpriseAccount();
        }

        //会员信息
        MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(startChargeReq.getMemberId());

        //发送充电指令
        DataType dataType;
        if (elecPileService.elecpileVersionDiffer(elecPile.getProgramVersion())) {
            dataType = new ElectricizeControl(startChargeReq.getGunNum(), startChargeReq.getCmdCode(), orderNum);
        } else {
            List<ElecStationPriceData> elecStationPriceData = elecStationPriceService.listElecStationPriceDataByStationId(elecPile.getElecStationId());
            dataType = new ElectricizeInterControl(startChargeReq.getGunNum(), startChargeReq.getCmdCode(), orderNum, elecStationPriceData, money);
        }
        TerminalMessage message = new TerminalMessage(elecPile.getPileRtua(), StdControlCode.CONTROL_CHARGE_START_STOP, dataType);
        boolean flag = MessageHandler.write(message);

        String gunNum = startChargeReq.getGunNum();
        if (gunNum.length() < 2) {// 低位补0
            gunNum = "0" + gunNum;
        }

        // 充电指令发送成功将用户id保存到redis，将当前发指令的时间保存到redis，添加读取枪状态定时器（20秒内收到确认帧就会移除）
        if (flag) {

            //保存充电结果 公众号去拉取该数据
            //redChargeDataService.putChargeResult(elecPile.getPileRtua(), elecGun.getGunNum(), memberInfo.getMobile(), 0);
            redChargeDataService.putChargeResult(elecPile.getPileRtua(), elecGun.getGunNum(), orderNum, 0);

            //先保存OrderComment
            OrderComment orderComment = new OrderComment();
            orderComment.setTenantCode(startChargeReq.getTenantCode());   //运营商ID
            orderComment.setTenantOperatorCode(elecStation.getTenantOperatorCode());//分销商
            orderComment.setHlhtTenantCode(startChargeReq.getHlhtTenantCode());//SAAS互联互通运营商
            orderComment.setCarNum(startChargeReq.getCarNum()); //车牌号

            orderComment.setHlhtOperatorId(startChargeReq.getHlhtOperatorId());//第三方运营商

            orderComment.setMemberId(memberInfo.getMemberId());

            //order_source;订单来源 0 公众号 1 APP  2小程序 3.刷卡 4.VIN码充电   9.第三方API  默认0
            //if (startChargeReq.getOrderSource().equals(CommanderEnum.API.getCode())) {
            //    orderComment.setHlhtOrderType("1");
            //}

            //各种类型的充电方式: //互联互通订单类型以tenant_code为基准,0为自主订单 1反向对接订单 2正向对接订单 3.内部正向外联, 默认0
            if (StringUtils.isBlank(startChargeReq.getHlhtTenantCode()) && StringUtils.isBlank(startChargeReq.getHlhtOperatorId())) {//运营商自己的桩
                orderComment.setHlhtOrderType("0");
            } else if (StringUtils.isNotBlank(startChargeReq.getHlhtTenantCode()) && StringUtils.isBlank(startChargeReq.getHlhtOperatorId())) {//其它SAAS运营商桩
                orderComment.setHlhtOrderType("2");
            } else if (StringUtils.isNotBlank(startChargeReq.getHlhtTenantCode()) && StringUtils.isNotBlank(startChargeReq.getHlhtOperatorId())) {//内部正向外联,其他SAAS运营商的桩
                orderComment.setHlhtOrderType("3");
                orderComment.setTenantCode(startChargeReq.getHlhtTenantCode());//设备方
                orderComment.setHlhtTenantCode(startChargeReq.getTenantCode());//瑞晨

                //瑞晨与第三方互联的互联账号信息 填入预订单中
                HlhtskBizOperator hlhtskBizOperator = hlhtskBizOperatorService.selectBizOperator(startChargeReq.getTenantCode(), startChargeReq.getHlhtOperatorId());
                orderComment.setMemberId(hlhtskBizOperator.getMemberId());

            } else {//第三方运营商
                orderComment.setHlhtOrderType("1");
            }

            orderComment.setElecStationId(elecPile.getElecStationId());
            orderComment.setElecPileId(elecPile.getElecPileId());
            orderComment.setElecGunId(elecGun.getElecGunId());
            orderComment.setCreatedTime(new Date());

            orderComment.setOrderNum(orderNum);

            //保存外部订单号
            if (StringUtils.isBlank(startChargeReq.getOutOrderNum())) {
                orderComment.setOutOrderNum(orderNum);
            } else {
                orderComment.setOutOrderNum(startChargeReq.getOutOrderNum());
            }

            orderComment.setAccountType(startChargeReq.getAccountType()); //支付的账户类型 0个人钱包 1企业钱包 默认0

            orderComment.setOrderSource(startChargeReq.getOrderSource()); //订单来源 0 公众号 1 APP  2小程序 3.刷卡 4.VIN码充电 9.第三方API  默认0
            orderComment.setTicketUsingType(startChargeReq.getTicketUsingType());//优先使用优惠券,默认1使用 0不使用

            orderComment.setStartType(startChargeReq.getStartType()); //启动方式 0 一般 1 刷卡 2 VIN码启动 3.先付后退 4.微信支付分 5.支付分(先充后付) 9其他方式 默认0
            orderComment.setCarVin(startChargeReq.getCarVin()); //vin码
            orderComment.setDriverId(startChargeReq.getDriverId());//司机ID
            orderComment.setCarNum(startChargeReq.getCarNum());//车牌

            orderCommentService.insertSelective(orderComment);

            //保存充电日志
            chargedProcessLogAssemble.assembleChargedProcessLog(ChargePhaseEnum.START, orderComment);

            return SocketConstant.SUCCESS;
        } else {
            //保存充电结果，下发指令失败
            //redChargeDataService.putChargeResult(elecPile.getPileRtua(), elecGun.getGunNum(), memberInfo.getMobile(), 1);
            redChargeDataService.putChargeResult(elecPile.getPileRtua(), elecGun.getGunNum(), orderNum, 1);
            return SocketConstant.FAIL;
        }
    }

    @Override
    public Integer query_stop_charge(StopChargeReq stopChargeRequest) {
        //验证码订单号是否准确
        OrderInfo orderInfo = orderInfoService.selectByOrderNum(stopChargeRequest.getOrderNum());
        if (orderInfo == null) {
            logger.error("停止充电失败,未找到对应的订单号。该订单号为：" + stopChargeRequest.getOrderNum());
            return SocketConstant.FAIL;
        }

        ElecPile pile = elecPileService.selectByPrimaryKey(orderInfo.getElecPileId());
        ElecGun gun = elecGunService.selectByPrimaryKey(orderInfo.getElecGunId());

        MemberAccount memberAccount = memberAccountMapper.selectByPrimaryKey(orderInfo.getMemberId());
        BigDecimal money;
        if ((SocketConstant.CON0 + "").equals(orderInfo.getAccountType())) {
            money = memberAccount.getAccount();
        } else if (SocketConstant.STR_CON2.equals(orderInfo.getAccountType())) {
            money = enterpriseSubmemberShareService.selectMoneyByTenantCodeAndMemberId(memberAccount.getTenantCode(), memberAccount.getMemberId());
        } else {
            money = memberAccount.getEnterpriseAccount();
        }
        //手动停止则添加标签
        //MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(orderInfo.getMemberId());

        //发送充电指令
        DataType dataType;
        if (elecPileService.elecpileVersionDiffer(pile.getProgramVersion())) {
            dataType = new ElectricizeControl(gun.getGunNum(), stopChargeRequest.getCmdCode(), orderInfo.getOrderNum());
        } else {
            List<ElecStationPriceData> elecStationPriceData = elecStationPriceService.listElecStationPriceDataByStationId(pile.getElecStationId());
            dataType = new ElectricizeInterControl(gun.getGunNum(), stopChargeRequest.getCmdCode(), orderInfo.getOrderNum(), elecStationPriceData, money);
        }
        //DataType dataType = new ElectricizeControl(gun.getGunNum(), SocketConstant.POWER_STOP, orderInfo.getOrderNum());
        TerminalMessage message = new TerminalMessage(pile.getPileRtua(), StdControlCode.CONTROL_CHARGE_START_STOP, dataType);
        boolean flag = MessageHandler.write(message);

        if (flag) {
            //保存充电结果
            //redChargeDataService.putChargeResult(pile.getPileRtua(), gun.getGunNum(), memberInfo.getMobile(), 0);
            redChargeDataService.putChargeResult(pile.getPileRtua(), gun.getGunNum(), orderInfo.getOrderNum(), 0);

            //记录停止方式
            //redChargeDataService.putStopMode(pile.getPileRtua(), gun.getGunNum(), memberInfo.getMobile(), stopChargeRequest.getStopType());
            redChargeDataService.putStopMode(pile.getPileRtua(), gun.getGunNum(), orderInfo.getOrderNum(), stopChargeRequest.getStopType());

            OrderComment orderComment = orderCommentService.selectByOrderNum(orderInfo.getOrderNum());
            //保存充电日志
            chargedProcessLogAssemble.assembleChargedProcessLog(ChargePhaseEnum.STOP, orderComment);

            return SocketConstant.SUCCESS;
        }

        //发送指令失败
        //redChargeDataService.putChargeResult(pile.getPileRtua(), gun.getGunNum(), memberInfo.getMobile(), 1);
        redChargeDataService.putChargeResult(pile.getPileRtua(), gun.getGunNum(), orderInfo.getOrderNum(), 1);

        return SocketConstant.FAIL;
    }

    /**
     * 互联互通启动成功时保存推送信息
     *
     * @param orderComment
     */
    private void createHlhtOrderNotify(OrderComment orderComment) {
        //如果是互联互通启动的订单就记录推送等信息
        HlhtTenantOrderNotify newOrderNotify = new HlhtTenantOrderNotify();
        newOrderNotify.setTenantCode(orderComment.getTenantCode());
        newOrderNotify.setTenantOperatorCode(orderComment.getTenantOperatorCode());
        newOrderNotify.setHlhtOperatorId(orderComment.getHlhtOperatorId());

        //还没有orderId
        //hlhtOrderNotify.setOrderId(orderComment.getOrderId());
        newOrderNotify.setOrderNum(orderComment.getOrderNum());
        newOrderNotify.setOutOrderNum(orderComment.getOutOrderNum());
        newOrderNotify.setMemberId(orderComment.getMemberId());
        //互联互通运营商的请求开始时间
        newOrderNotify.setStartChargeReqTime(orderComment.getCreatedTime());
        newOrderNotify.setCreatedTime(new Date());
        hlhtTenantOrderNotifyService.insertSelective(newOrderNotify);
    }

    /**
     * 互联互通启动成功时保存推送信息
     *
     * @param orderComment
     */
    private void updateHlhtOrderNotify(OrderComment orderComment) {
        //如果是互联互通启动的订单就记录推送等信息
        HlhtTenantOrderNotify updateOrderNotify = new HlhtTenantOrderNotify();
        updateOrderNotify.setOutOrderNum(orderComment.getOutOrderNum());

        //互联互通运营商的请求结束时间
        updateOrderNotify.setStopChargeReqTime(new Date());
        updateOrderNotify.setLastUpdatedTime(new Date());
        hlhtTenantOrderNotifyService.updateByPrimaryKeySelective(updateOrderNotify);
    }

    /**
     * 充电前,会员信息校验
     *
     * @param startChargeRequest
     * @return
     */
    private Integer checkStart(StartChargeReq startChargeRequest) {
        ElecPile pile = elecPileService.selectByPrimaryKey(startChargeRequest.getElecPileId());
        MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(startChargeRequest.getMemberId());

        //判断支付的账户类型 0个人钱包 1企业钱包 2共享余额 3先付后退钱包 4.支付分钱包 默认0
        BigDecimal money = null;
        if ((SocketConstant.CON0 + "").equals(startChargeRequest.getAccountType())) {
            money = memberInfo.getJoinMemberAccount().getAccount();
        } else if (SocketConstant.STR_CON2.equals(startChargeRequest.getAccountType())) {
            money = enterpriseSubmemberShareService.selectMoneyByTenantCodeAndMemberId(memberInfo.getTenantCode(), startChargeRequest.getMemberId());
            if (money == null) {
                logger.error("不满足共享余额充电的条件,请检查后重试,该会员为:" + memberInfo.getMobile());
                return SocketConstant.EXCEPTION;
            }

        }else {
            money = memberInfo.getJoinMemberAccount().getEnterpriseAccount();
        }

        //单冲用户最小启动充电余额
        BigDecimal start_charge_account_limit = tenantSettingService.query_start_charge_account_limit(memberInfo.getTenantCode());


        //用户是否在充电 0不是，1正充电                         充电类型 0单冲 1多充 默认0
        if ("1".equals(memberInfo.getChargeStatus()) && "0".equals(memberInfo.getChargeType())) {

            //如果上笔订单异常，则可以发起下笔充电、比如桩离网
            OrderInfo lastOrderInfo = orderInfoService.selectNewOrderByMemberId(memberInfo.getMemberId());
            if (lastOrderInfo == null) {
                return SocketConstant.USING;
            }


            //上笔挂单，但是桩未离线也不允许充电
            ElecPile lastElecPile = elecPileService.selectByPrimaryKey(lastOrderInfo.getElecPileId());
            if (!SocketConstant.STR_CON2.equals(lastOrderInfo.getStatus()) && SocketConstant.STR_CON1.equals(lastElecPile.getStatus())) {
                return SocketConstant.USING;
            }

            // 1多充
        } else if (memberInfo.getChargeType().equals(SocketConstant.CON1 + "")) {
            Integer number = orderInfoService.countElecOrder(memberInfo) + 1;

            //一号多充金额限制
            BigDecimal mult_charge_account_limit = tenantSettingService.query_mult_charge_account_limit(memberInfo.getTenantCode());
            BigDecimal startMoney = mult_charge_account_limit.multiply(new BigDecimal(number));
            //多充 一车充电与普通用户一致
            if (number == 1) {
                startMoney = start_charge_account_limit;
            }
            //多充会员启动的余额大于  单次启动金额*（正在充电订单数+1）
            if (startMoney.compareTo(money) == 1) {
                return SocketConstant.EXCEPTION;
            }
        }

        //如果没有参数值,就取默认值
        //PlatformSetting platformSetting = platformSettingService.selectSettingByParaName(PlatformConstant.START_CHARGE_ACCOUNT_LIMIT);
        //BigDecimal start_charge_account_limit = PlatformConstant.DEFALUT_START_CHARGE_ACCOUNT_LIMIT;
        //try {
        //    if (platformSetting != null) {
        //        start_charge_account_limit = new BigDecimal(platformSetting.getParaValue());
        //    }
        //} catch (Exception e) {
        //    logger.error("start_charge_account_limit 无效", e);
        //}


        if (money == null || money.intValue() < start_charge_account_limit.intValue()) {
            logger.warn("钱包余额2:" + money);
            return SocketConstant.EXCEPTION;
        }

        //添加8秒枪约束,防止抢枪
        if (!redisService.setIfAbsent(DataUtil.getCheckPileTime(pile.getPileRtua(), startChargeRequest.getGunNum()), new Date().getTime(), 8000L)) {
            logger.warn("充电失败,充电约束桩:{},枪:{}", pile.getPileRtua(),startChargeRequest.getGunNum());
            return SocketConstant.UNIQUE;
        }

        ////添加枪约束;
        //String duplicationClickTime = redisService.getRedis(DataUtil.getCheckPileTime(pile.getPileRtua(), startChargeRequest.getGunNum()));
        //if (duplicationClickTime != null) {
        //    Long timeDiff = (System.currentTimeMillis() - Long.valueOf(duplicationClickTime)) / 1000;
        //    if (timeDiff < 8) {
        //        redisService.putRedis(DataUtil.getCheckPileTime(pile.getPileRtua(), startChargeRequest.getGunNum()), String.valueOf(new Date().getTime()));
        //        logger.warn("充电失败,充电约束的值为duplicationClickTime=" + duplicationClickTime);
        //        return SocketConstant.UNIQUE;
        //    }
        //}

        redisService.putRedis(DataUtil.getCheckPileTime(pile.getPileRtua(), startChargeRequest.getGunNum()), String.valueOf(new Date().getTime()));

        return SocketConstant.SUCCESS;
    }

    private Integer checkStop(StopChargeReq stopChargeRequest) {
        OrderInfo order = orderInfoService.selectByOrderNum(stopChargeRequest.getOrderNum());
        if (order == null) {
            logger.error("停止充电失败,未找到对应的订单号。该订单号为：" + stopChargeRequest.getOrderNum());
            return SocketConstant.FAIL;
        }

        if ((SocketConstant.CON2 + "").equals(order.getStatus())) {
            logger.error("该订单号为：{},已结算，不能重复停止。", stopChargeRequest.getOrderNum());
            return SocketConstant.FAIL;
        }

        return SocketConstant.SUCCESS;
    }

    /**
     * 发送远程升级指令
     */
    public Integer sendRemoteUpdate(Long pileId, String fileName, String startType) {
        ElecPile pile = elecPileService.selectByPrimaryKey(pileId);
        String measuringPoint = "00"; // 测量点号，面前规定为00;
        String password = pile.getPassword(); // 桩密码;

        String host = remoteUpdateConfig.getHost();
        if (host.endsWith("com")) {
            try {
                //域名解析为IP
                host = InetAddress.getByName(host).getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        String host0 = "";
        String port0 = "";
        String user0 = "";
        String rPassword0 = "";
        String fileName0 = "";
        String filePath0 = "";

        //新亚厂家
        if (tenantManufacturerService.isManufacturerCodeByEpId(WebConstant.XY_MANUFACTURE_CODE, pile.getManufacturerId())) {
            host0 = stringToHex(RemoteUpdateConfig.XY_HOST, 20).toUpperCase(); // 主机地址;     长度20字节，不足补00
            port0 = stringToHex(RemoteUpdateConfig.XY_PORT, 5).toUpperCase(); // 端口号; 长度5字节，不足补00
            user0 = stringToHex(RemoteUpdateConfig.XY_USER, 20).toUpperCase(); // 用户名，长度20字节，不足补00
            rPassword0 = stringToHex(RemoteUpdateConfig.XY_PASSWORD, 20).toUpperCase(); // 密码，长度20字节，不足补00
            fileName0 = stringToHex(fileName, 25).toUpperCase(); // 文件名
            filePath0 = stringToHex(RemoteUpdateConfig.XY_FILEPATH, 25).toUpperCase(); // 文件路劲
        } else {
            host0 = stringToHex(host, 20).toUpperCase(); // 主机地址;     长度20字节，不足补00
            port0 = stringToHex(remoteUpdateConfig.getPort(), 5).toUpperCase(); // 端口号; 长度5字节，不足补00
            user0 = stringToHex(remoteUpdateConfig.getUser(), 20).toUpperCase(); // 用户名，长度20字节，不足补00
            rPassword0 = stringToHex(remoteUpdateConfig.getPassword(), 20).toUpperCase(); // 密码，长度20字节，不足补00
            fileName0 = stringToHex(fileName, 25).toUpperCase(); // 文件名
            filePath0 = stringToHex(remoteUpdateConfig.getFilePath(), 25).toUpperCase(); // 文件路劲
        }


        // .bin的后缀，长度50字节，不足补00
        String startType0 = "0" + startType; // 启动类型;
        DataType dataType = new RemoteUpdate(measuringPoint, DataUtil.PERMISSON[1], password, host0, port0, user0,
                rPassword0, fileName0, startType0, filePath0);
        TerminalMessage message = new TerminalMessage(pile.getPileRtua(), StdControlCode.REMOTE_UPGRADE, dataType);
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    /**
     * 发送校时指令
     *
     * @param pileId
     * @return
     */
    @Override
    public int sendTimingDate(Long pileId) {
        ElecPile elecPile = elecPileService.selectByPrimaryKey(pileId);

        // .bin的后缀，长度50字节，不足补00
        TimingDate timingData = new TimingDate();
        timingData.setDate();
        TerminalMessage message = new TerminalMessage(elecPile.getPileRtua(), StdControlCode.WRITE_OBJ_PARAM_REALTIME, timingData);
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    @Override
    public void updateOrderBalanceByRedis(Long pileId, String gunNum) {

    }

    @Override
    public int sendUnlock(Long pileId, String gunNum) {
        ElecPile pile = elecPileService.selectByPrimaryKey(pileId);

        // .bin的后缀，长度50字节，不足补00
        UnlockControl dataType = new UnlockControl();
        dataType.setGunNum(SocketConstant.CON0 + gunNum);
        dataType.setUnlockCode("0" + SocketConstant.UNLOCK_SUCCESS);

        TerminalMessage message = new TerminalMessage(pile.getPileRtua(), StdControlCode.CONTROL_UNLOCK, dataType);
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    @Override
    public int sendCutPowerCode(PowerOffReq powerOffReq) {
        ElecPile elecPile = elecPileService.selectByPrimaryKey(powerOffReq.getPileId());

        // .bin的后缀，长度50字节，不足补00
        PowerOffData dataType = new PowerOffData();
        dataType.setPowerOffType(SocketConstant.CON0 + powerOffReq.getPowerType());

        TerminalMessage message = new TerminalMessage(elecPile.getPileRtua(), StdControlCode.POWER_OFF_C3_REQUEST, dataType);
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    @Override
    public int sendUserAccount(UserAccountReq userAccountReq) {
        ElecPile elecPile = elecPileService.selectByPrimaryKey(userAccountReq.getPileId());

        MemberAccount memberAccount = memberAccountMapper.selectByPrimaryKey(userAccountReq.getMemberId());
        MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(userAccountReq.getMemberId());
        OrderInfo orderInfo = orderInfoService.selectNewOrderByMemberId(memberAccount.getMemberId());
        ElecGun elecGun = elecGunService.selectByPrimaryKey(orderInfo.getElecGunId());

        //选择有效钱包
        BigDecimal account;
        //支付的账户类型 0个人钱包 1企业钱包 2共享余额 默认0
        if (SocketConstant.STR_CON2.equals(orderInfo.getAccountType())) {
            MemberInfo enterMemberInfo = memberInfoService.selectByPrimaryKey(memberInfo.getEnterpriseMemberId());
            MemberAccount memberAccount1 = memberAccountMapper.selectByPrimaryKey(enterMemberInfo.getMemberId());
            account = memberAccount1.getEnterpriseAccount();
        } else if (SocketConstant.STR_CON1.equals(orderInfo.getAccountType())) {
            account = memberAccount.getEnterpriseAccount();
        } else {
            account = memberAccount.getAccount();
        }


        if (account.compareTo(new BigDecimal("1000")) == 1) {
            account = new BigDecimal("1000");
        }

        UserAccountData dataType = new UserAccountData();
        if (elecGun.getGunNum().length() == 1) {
            dataType.setGunNum("0" + elecGun.getGunNum());
        } else {
            dataType.setGunNum(elecGun.getGunNum());
        }
        dataType.setUserAccount(ToFrameUtil.accountToFrame(account));

        TerminalMessage message = new TerminalMessage(elecPile.getPileRtua(), StdControlCode.USER_ACCOUNT_C4_REQUEST, dataType);
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    @Override
    public Integer check_power(Long pileId, int second) {
        ElecPile elecPile = elecPileService.selectByPrimaryKey(pileId);
        ElecPilePowerData dataType = new ElecPilePowerData();
        dataType.setTime("00 00");
        TerminalMessage message = new TerminalMessage(elecPile.getPileRtua(), StdControlCode.ELEC_PILE_POWER_REQUEST, dataType);
        if (message.getMsta() == null) {
            message.setMsta("00 00");
        }
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    @Override
    public Integer limit_power(Long pileId, BigDecimal maxPower) {
        ElecPile elecPile = elecPileService.selectByPrimaryKey(pileId);
        ElecPileLimitPowerData dataType = new ElecPileLimitPowerData();
        dataType.setMaxPower(maxPower);
        TerminalMessage message = new TerminalMessage(elecPile.getPileRtua(), StdControlCode.ELEC_PILE_LIMIT_POWER_REQUEST, dataType);
        if (message.getMsta() == null) {
            message.setMsta("00 00");
        }
        boolean flag = MessageHandler.write(message);
        if (flag == true) {
            return SocketConstant.SUCCESS;
        }
        return SocketConstant.FAIL;
    }

    /**
     * 字符串转16进制
     *
     * @param str
     * @return
     */
    private String stringToHex(String str, int length) {
        StringBuffer sb = new StringBuffer();
        int remainder = length - str.length();
        if (remainder < 0) {
            return null;
        }
        for (int i = 0; i < str.length(); i++) {
            int dec = str.charAt(i);
            String hex = Integer.toHexString(dec);
            if (hex.length() < 2) {
                hex = "0" + hex;
            }
            sb.append(hex).append(" ");
        }
        if (remainder > 0) {
            for (int i = 0; i < remainder; i++) {
                sb.append("00").append(" ");
            }
        }
        return sb.toString().trim();
    }

//    /**
//     * 结算桩对应的redis数据;
//     *
//     * @param pileId
//     * @param gunNum
//     */
//    @Override
//    public void updateOrderBalanceByRedis(Long pileId, String gunNum) {
//        ElecPile pile = elecPileMapper.selectByPrimaryKey(pileId);
//        List<com.jt.evcharger.redis.Order> list = (List<com.jt.evcharger.redis.Order>) redisService.getObjects(new com.jt.evcharger.redis.Order(pile.getRtua()));
//        for (com.jt.evcharger.redis.Order order : list) {
//            try {
//                logger.warn("订单异常结算：桩地址:" + pile.getRtua() + "订单id:" + order.getKey());
//                orderService.updateOrder(order.getOrderId(), SocketConstant.STOP_FAULT);
//                Order order0 = orderService.selectByPrimaryKey(order.getOrderId());
//                //如果是曹操订单就做推送处理
//                PlatformUser platformUserExt = platformUserExtMapper.selectByMemberId(order0.getMember());
//                if (order0 != null && order0.getOutOrderNum() != null && platformUserExt != null && platformUserExt.getIsFinishNotify() == 1) {
//                    //CaoCaoUtil.postCc(order0.getOutOrderNum());
//
//                    ElecGun gun = gunMapper.selectByPrimaryKey(order0.getGun());
//                    String epNo = gun.getEpNo();//枪编号
//                    if (CecNotifyUtil.CC_APP_ID.equals(platformUserExt.getAppId())) {//CAOCAO
//                        CaoCaoUtil.postCc(order0.getOutOrderNum());
//                    } else if (CecNotifyUtil.DD_APP_ID.equals(platformUserExt.getAppId())) {//DD
//                        CommandStopReq commandStopReq = new CommandStopReq();
//
//
//                        commandStopReq.setOrderId(String.valueOf(order0.getId()));
//                        commandStopReq.setStartChargeSeq(order0.getOutOrderNum());
//                        commandStopReq.setConnectorID(epNo);
//
//                        //推送停止消息
//                        CecNotifyUtil.notify_query_stop_charge(commandStopReq, CecNotifyUtil.DD_MQ_PREFIX);
//                    } else if (CecNotifyUtil.D1_APP_ID.equals(platformUserExt.getAppId())) {//D1
//                        CommandStopReq commandStopReq = new CommandStopReq();
//                        commandStopReq.setOrderId(String.valueOf(order0.getId()));
//                        commandStopReq.setStartChargeSeq(order0.getOutOrderNum());
//                        commandStopReq.setConnectorID(epNo);
//
//                        //推送停止消息
//                        CecNotifyUtil.notify_query_stop_charge(commandStopReq, CecNotifyUtil.D1_MQ_PREFIX);
//                    } else if (CecNotifyUtil.WC_APP_ID.equals(platformUserExt.getAppId())) {//WC
//                        CommandStopReq commandStopReq = new CommandStopReq();
//                        commandStopReq.setOrderId(String.valueOf(order0.getId()));
//                        commandStopReq.setStartChargeSeq(order0.getOutOrderNum());
//                        commandStopReq.setConnectorID(epNo);
//
//                        //推送停止消息
//                        CecNotifyUtil.notify_query_stop_charge(commandStopReq, CecNotifyUtil.WC_MQ_PREFIX);
//                    }
//                }
//
//                //非平台用户才需推送信息给终端用户
//                if (platformUserExt == null) {
//                    CommandStopReq commandStopReq = new CommandStopReq();
//                    commandStopReq.setOrderId(String.valueOf(order0.getId()));
//                    commandStopReq.setStartChargeSeq(order0.getOutOrderNum());
//                    WeChatMsgUtil.sendFinishMsg(order0.getOrderSource(), commandStopReq);
//                }
//
//                //推送到open，针对恒通单个用户
//                if (order0.getMember() == HtNotifyUtil.HT_MID_8065 ||
//                        order0.getMember() == HtNotifyUtil.HT_MID_8091 ||
//                        order0.getMember() == HtNotifyUtil.HT_MID_8046) {
//                    HtNotifyUtil.sendOrderId(order0.getId());
//                }
//
//                //推送订单到羊城充
//                Long start = System.currentTimeMillis();
//                YccMsgUtil.sendFinishOrder(order0.getId());
//                logger.warn("发送订单到羊城通:" + (System.currentTimeMillis() - start) / 1000 + "秒");
//
//                //APP订单做推送
//                if (WebConstant.CON1.equals(order0.getOrderSource())) {
//                    Member member = memberMapper.selectByPrimaryKey(order0.getMember());
//                    AppMsgUtil.sendOrderStopReason(member.getMobile(), order0.getStopReason(), order0.getOrderNum());
//                }
//
//            } catch (Exception e) {
//                logger.error("CommandServiceImpl.updateOrderBalanceByRedis()方法结算出错");
//                e.printStackTrace();
//            }
//        }
//    }

    public static void main(String[] args) {
        System.out.println(String.format("%08d", 123));
        try {
            System.out.println(InetAddress.getByName("v0.ftp.upyun.com").getHostAddress());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }
}
